package bean;

import java.util.ArrayList;
import java.util.zip.CRC32;

import util.Util;

public class Pacote {
	private byte[] preambulo;
	private byte[] enderecoDestino;
	private byte[] enderecoOrigem;
	private byte[] tipoRede;
	private ArrayList<Byte> dados;
	private byte[] crc;

	public static boolean simulaErro = false;

	public Pacote() {

		// seta preambulo
		this.preambulo = new byte[8];
		for (int i = 0; i < 7; i++) {
			preambulo[i] = (byte) Integer.parseInt("10101010", 2);
		}
		preambulo[7] = (byte) Integer.parseInt("10101011", 2);

		// enderecos
		this.enderecoDestino = new byte[6];
		this.enderecoOrigem = new byte[6];

		this.enderecoOrigem = Util.getEnderecoMaquina();

		// try {
		// InetAddress address = InetAddress.getLocalHost();
		// System.out.println(address);
		// NetworkInterface ni = NetworkInterface.getByInetAddress(address);
		// if (ni != null) {
		// byte[] mac = ni.getHardwareAddress();
		// if (mac != null) {
		//
		// // Extract each array of mac address and convert it to hexa
		// // with the
		// // following format 08-00-27-DC-4A-9E.
		//
		// System.out.println("Mac Address: " + mac.length);
		// for (int i = 0; i < mac.length; i++) {
		// System.out.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : "");
		// }
		// } else {
		// System.out.println("Address doesn't exist or is not accessible.");
		// }
		// } else {
		// System.out.println("Network Interface for the specified address is not found.");
		// }
		// } catch (UnknownHostException e) {
		// e.printStackTrace();
		// } catch (SocketException e) {
		// e.printStackTrace();
		// }

		// seta tipo rede
		this.tipoRede = new byte[2];
		tipoRede[0] = (byte) Integer.parseInt("00000000", 2);
		tipoRede[1] = (byte) Integer.parseInt("00001000", 2);

		this.dados = new ArrayList<Byte>();
	}

	public byte[] getPreambulo() {
		return preambulo;
	}

	public void setPreambulo(byte[] preambulo) {
		this.preambulo = preambulo;
	}

	public byte[] getEnderecoDestino() {
		return enderecoDestino;
	}

	public void setEnderecoDestino(byte[] enderecoDestino) {
		this.enderecoDestino = enderecoDestino;
	}

	public byte[] getEnderecoOrigem() {
		return enderecoOrigem;
	}

	public void setEnderecoOrigem(byte[] enderecoOrigem) {
		this.enderecoOrigem = enderecoOrigem;
	}

	public byte[] getTipoRede() {
		return tipoRede;
	}

	public void setTipoRede(byte[] tipoRede) {
		this.tipoRede = tipoRede;
	}

	public ArrayList<Byte> getDados() {
		return dados;
	}

	public boolean setDados(ArrayList<Byte> dados) {
		if (dados.size() > 1500) {
			return false;
		} else {
			this.dados = dados;
			return true;
		}
	}

	public byte[] getCrc() {
		gerarCRC();
		return crc;
	}

	public boolean adicionarByteDados(byte byteDado) {
		if (dados.size() < 1500) {
			dados.add(byteDado);
			return true;
		}
		return false;
	}

	public byte[] montarVetorBytes() {
		int tamanhoVetor = dados.size() + 22;
		byte[] bytesPacotes = new byte[tamanhoVetor];

		for (int i = 0; i < 8; i++) {
			bytesPacotes[i] = preambulo[i];
		}

		for (int i = 0; i < 6; i++) {
			bytesPacotes[i + 8] = enderecoDestino[i];
		}

		for (int i = 0; i < 6; i++) {
			bytesPacotes[i + 8 + 6] = enderecoOrigem[i];
		}

		for (int i = 0; i < 2; i++) {
			bytesPacotes[i + 8 + 6 + 6] = tipoRede[i];
		}

		for (int i = 0; i < dados.size(); i++) {
			bytesPacotes[i + 8 + 6 + 6 + 2] = dados.get(i);
		}
		return bytesPacotes;
	}

	public byte[] montarVetorBytesCRC() {
		byte[] vetor = montarVetorBytes();
		byte[] vetorCompleto = new byte[vetor.length + 4];
		for (int i = 0; i < vetor.length; i++) {
			vetorCompleto[i] = vetor[i];
		}
		for (int i = 0; i < 4; i++) {
			vetorCompleto[vetor.length + i] = crc[i];
		}
		return vetorCompleto;
	}

	private void gerarCRC() {

		CRC32 checksum = new CRC32();
		byte[] vetor = montarVetorBytes();
		if (simulaErro) {
			if (vetor[0] == 0) {
				vetor[0] = 1;
			} else {
				vetor[0] = 0;
			}
		}
		checksum.update(vetor, 0, vetor.length);
		Long l = checksum.getValue();
		String crcl = Long.toBinaryString(l);
		this.crc = new byte[4];

		for (int i = 0; i < crcl.length(); i += 8) {
			if (i + 8 > crcl.length()) {
				crc[i / 8] = (byte) Integer.parseInt(crcl.substring(i), 2);
			} else {
				crc[i / 8] = (byte) Integer.parseInt(crcl.substring(i, i + 8), 2);
			}
		}

	}
}
